#  Makefile for smoke-testing ftnchek.  Say ``make'' to make all checks.
#
#

# This defn uses version of dcl2inc.awk in the parent directory.
DCL2INC		= $(NAWK) -f ../dcl2inc.awk

# This defn uses version of ftnchek in the parent directory.
FTNCHEK		= ../ftnchek

# OKAY subdirectory is where the correct output files are stored.
OKAY		= Okay

# VARY subdirectory is where the varying output files are stored.
VARY		= Vary


# COMPARE invokes the comparison script to check new vs archive.
COMPARE		= ./Compare.sh $(OKAY) $(VARY)

# DEFAULT_FLAGS is the set of Ftnchek flags used by the default rule.
# Note: The default rule also sets -f77 via the environment mechanism
# in order to check that mechanism.
DEFAULT_FLAGS	= -list -symt -port

MAKE		= make FTNCHEK=$(FTNCHEK) OKAY=$(OKAY) VARY=$(VARY)

CP              = /bin/cp
MV		= /bin/mv
# We need new awk, either AT&T nawk or GNU gawk.  However, IBM RS/6000 AIX
# calls it awk.
#NAWK		= awk
#NAWK		= gawk
NAWK		= nawk
RM		= /bin/rm -f
CSH		= /bin/csh -f
SHELL		= /bin/sh


.SUFFIXES: .chk .f .prj .fcl .fc1 .fc2 .fc3 .fc4 .fc5 .fc6 .fc7 .fc8 .fc9 \
 .fcA .fcB .fcC .fcD .fcE .fcF


#=======================================================================
#
#                   Definitions of File Groups
#
#
# LISTOUT programs are simple, and all use the default options or else the
# options given in their .opt file.  These produce listing files *.fcl
# Note: Those with .opt files may have associated routines in other
# files that do not appear here.

LISTOUT= average.f backslash.f chestnuts.f comclash.f comcmp.f\
 complex.f comtest.f comusage.f correct.f dims.f do_enddo.f\
 help.f include.f namelist.f noblanks.f strings.f unixincluded.f\
 dectab.f intrinstest.f

# set of files for testing -arguments setting
ARGS= args01.f args02.f args03.f args04.f args05.f args06.f\
 args07.f args08.f args09.f args10.f args11.f args12.f\
 args13.f args14.f args15.f

# set of files for testing -array setting
ARRAY= arrayclash.f

# Set of files for testing -trun -port -f77 options and -word setting
EXPR= assign.f

# set of files for testing -common setting
COMMON= comcmp.f comusage.f

# set of files for testing dcl2inc processing
DCL2INCFILES= t208x.f

# set of files for testing -makedcls setting
MAKEDCLS= dims.f namelist.f\
 t208a.f t208b.f t208c.f t208d.f t208e.f t208f.f t208g.f t208h.f \
 t208i.f t208j.f t208k.f t208l.f t208m.f t208n.f t208o.f t208p.f \
 t208q.f t208r.f t208s.f t208t.f t208u.f t208v.f t208w.f t208x.f

# set of files for testing -usage setting
USAGE= usage.f

# set of files for testing -vcg switch (use target checkvcg)
VCGLIST= comcmp.f comusage.f

#=======================================================================
#
#                   Default Rules
#
# Rule for creating source code listing file, suffix .fcl.  Stdout and
# stderr are merged and environment mechanism for setting command
# options is tested.

.f.fcl:
	@if [ -f $*.opt ] ; then \
	  FTNCHEK_F77=1; export FTNCHEK_F77; \
	  $(FTNCHEK) `cat $*.opt` > $@ 2>&1 ; \
	else \
	  FTNCHEK_F77=1; export FTNCHEK_F77; \
	  $(FTNCHEK) $(DEFAULT_FLAGS) $< > $@ 2>&1 ; \
	fi


# Rule for creating project file.  The .fcl file is made as a side-effect.
.f.prj:
	if [ -f $*.opt ] ; then \
	   $(FTNCHEK) -project `cat $*.opt` > $*.fcl 2>&1 ; \
	else \
	   $(FTNCHEK) -project $(DEFAULT_FLAGS) $< > $*.fcl 2>&1 ; \
	fi


# Rule for running checks on source code listing.  If OKAY directory does
# not exist, it is created.  If OKAY code listing does not exist, it
# is created and moved into OKAY.  Note: In this case, you must examine
# the results to see if it is really OK!
.f.chk:
	@-$(RM) $*.fcl
	@$(MAKE) FTNCHEK='$(FTNCHEK)' $*.fcl "DEFAULT_FLAGS=$(DEFAULT_FLAGS)"
	@$(COMPARE) $*.fcl



#=======================================================================
#
#		Targets.
#
#

all:	check

check:	announce checkall
	@echo "check done"

announce:
	@echo "============================================================"
	@echo "There should be no file differences reported by these tests."
	@echo "Output files matching master output files will be removed,"
	@echo "leaving any erroneous output files in directory $(VARY)"
	@echo "for manual examination."
	@echo "============================================================"

# To avoid problems later, see if invoked with wrong awk.  This target does
# not verify that it is the right awk, but catches the situation where
# make is using the default NAWK=nawk and nawk does not exist.
testfornawk:
	@if [ ! -x "`which $(NAWK)`" ]; \
	then \
	  echo ; \
	  echo 'PROBLEM: $(NAWK) not found, dcl2inc will not work.  It';\
	  echo 'requires the new awk. If your system has new awk';\
	  echo 'under the name awk or gawk, invoke "make NAWK=awk"';\
	  echo 'or "make NAWK=gawk".  Otherwise obtain AT&T nawk or GNU gawk.';\
	  echo ; \
	  exit 1 ; \
	fi

checkall:	checksyntax checksettings checkother

checksyntax:	checklistings checkexpr
checksettings:	checkargs checkarray checkcommon checkoutput checkusage
checkother:	checkproject checkmakedcls checkdcl2inc
# the following check is not included in checkall since -vcg is optional
checkoptional:	checkvcg

clean mostlyclean clobber distclean realclean spotless:
	-$(RM) *.dc[ln0-9] *.fc[l0-9A-F] *.pcl *.prj *.inc *.vcg
	-$(RM) *.i *.o
	-$(RM) *~ \#*
	-$(RM) a.out core
	-$(RM) $(VARY)/*

# checklistings checks listing output on programs in LISTOUT
checklistings: announcelistings $(LISTOUT:.f=.chk)
	@-echo "done"

# Some systems do not have echo -n option, so to suppress newline
# in a portable way, we use this `awk'ward kluge.
announcelistings:
	@-echo|awk '{printf("%s","checking listing output:");}'

# Next series of targets checks variations of output as options change.
# The output files are named *.fc[1-9A-F] for different cases.  Note that
# in some instances the same source file is also in a set that is used
# to check source listing as usual, with output file named *.fcl

# checkexpr checks listing output for various size & type clashes in
# expressions and assignment stmts
checkexpr:
	@-echo |awk '{printf("%s","checking size and type mismatch:");}'
	@for f in $(EXPR:.f=) ; \
	do \
	 $(FTNCHEK) -notrun -noport -nof77 -lis    $$f.f > $$f.fc1 ; \
	 $(COMPARE) $$f.fc1 ; \
	 $(FTNCHEK) -notrun -noport   -f77         $$f.f > $$f.fc2 ; \
	 $(COMPARE) $$f.fc2 ; \
	 $(FTNCHEK) -notrun   -port -nof77         $$f.f > $$f.fc3 ; \
	 $(COMPARE) $$f.fc3 ; \
	 $(FTNCHEK) -notrun   -port   -f77         $$f.f > $$f.fc4 ; \
	 $(COMPARE) $$f.fc4 ; \
	 $(FTNCHEK)   -trun -noport -nof77         $$f.f > $$f.fc5 ; \
	 $(COMPARE) $$f.fc5 ; \
	 $(FTNCHEK)   -trun -noport   -f77         $$f.f > $$f.fc6 ; \
	 $(COMPARE) $$f.fc6 ; \
	 $(FTNCHEK)   -trun   -port -nof77         $$f.f > $$f.fc7 ; \
	 $(COMPARE) $$f.fc7 ; \
	 $(FTNCHEK)   -trun   -port   -f77         $$f.f > $$f.fc8 ; \
	 $(COMPARE) $$f.fc8 ; \
	 $(FTNCHEK)   -trun   -port -nof77 -word=2 $$f.f > $$f.fcA ; \
	 $(COMPARE) $$f.fcA ; \
	 $(FTNCHEK)   -trun   -port -nof77 -word=4 $$f.f > $$f.fcB ; \
	 $(COMPARE) $$f.fcB ; \
	 $(FTNCHEK)   -trun   -port -nof77 -word=8 $$f.f > $$f.fcC ; \
	 $(COMPARE) $$f.fcC ; \
	done
	@-echo "done"

# checkargs checks the -args=n setting
checkargs:
	@-echo |awk '{printf("%s","checking -args setting:");}'
	@$(MAKE) FTNCHEK='$(FTNCHEK)' \
		CheckSetting "SETTING=-args" "RANGE=0 1 2 3" \
		"FLIST=$(ARGS)" "FLAGS="
	@-echo "done"

# checkarray checks the -array=n setting
checkarray:
	@-echo |awk '{printf("%s","checking -array setting:");}'
	@$(MAKE) FTNCHEK='$(FTNCHEK)' \
		CheckSetting "SETTING=-array" "RANGE=0 1 2 3" \
		"FLIST=$(ARRAY)" "FLAGS=-port"
	@-echo "done"

#checkcommon checks the -common=n setting
checkcommon:
	@-echo |awk '{printf("%s","checking -common setting:");}'
	@$(MAKE) FTNCHEK='$(FTNCHEK)' \
		CheckSetting "SETTING=-common" "RANGE=0 1 2 3" \
		"FLIST=$(COMMON)" "FLAGS=-nof77"
	@-echo "done"

checkdcl2inc: testfornawk
	@-echo |awk '{printf("%s","checking dcl2inc processing:");}'
	@for f in $(DCL2INCFILES) ; \
	do \
		b=`basename $$f .f` ; \
		$(RM) $$b.dcl $$b.dcn $$b.err $$b.mak ; \
		$(RM) *.inc ; \
		$(FTNCHEK) -makedcls=1 $$f 1>/dev/null 2>/dev/null ; \
		$(DCL2INC) $$b.dcl >$$b.mak 2>$$b.err ; \
		for g in $$b.dcl $$b.dcn $$b.mak $$b.err *.inc ; \
		do \
			$(COMPARE) $$g ; \
		done ; \
	done
	@-echo "done"

# checkoutput checks the -output=file string setting
checkoutput:
	@-echo |awk '{printf("%s","checking -output setting:");}'
	@$(FTNCHEK) -symt -list -port -out=average.out average.f 2> average.fc2
	@-$(COMPARE) average.out
	@-$(COMPARE) average.fc2
	@-echo "done"

# checkusage checks the -usage=n setting
checkusage:
	@-echo |awk '{printf("%s","checking -usage setting:");}'
	@$(MAKE) FTNCHEK='$(FTNCHEK)' \
		CheckSetting "SETTING=-usage" "RANGE=0 1 2 3" \
		"FLIST=$(USAGE)" "FLAGS="
	@-echo "done"

# checkproject checks creation and use of project files
# Note that correct.f is used in LISTOUT also, but with default
# compilation options.  So we make listing file suffix .fc1 here

checkproject:
	@-echo |awk '{printf("%s","checking project files:");}'
	@$(RM) correct.prj correct.fc1 correct.pcl
	@$(MAKE) FTNCHEK='$(FTNCHEK)' correct.prj
	@$(MAKE) FTNCHEK='$(FTNCHEK)' correct.pcl
	@-for f in correct.fc1 correct.prj correct.pcl ; \
	do \
	    $(COMPARE) $$f ; \
	done
	@-echo "done"


# Need explicit rule since the default rule is used by listing-file check
correct.prj: correct.f
	@$(FTNCHEK) -project correct.f > correct.fc1 2>&1

#  This target creates output listing file from project file input
correct.pcl: correct.f
	@$(FTNCHEK) correct.prj > correct.pcl 2>&1

# Check the generation of declarations files.  Listing goes to /dev/null.
# The values in MAKEDCLS_VALS are used as 3rd char in .fc? suffix.  They
# are converted to -makedcls=num values by raising 2 to the power.  Thus
# file.dc0 contains -makedcls=1, ... file.dc8 contains -makedcls=256.
# There is also a test to be sure that empty .dcl files are removed
# automatically as they should be.
MAKEDCLS_VALS	= 0 1 2 3 4 5 6 7 8
checkmakedcls:
	@-echo |awk '{printf("%s","checking -makedcls setting:");}'
	@for n in $(MAKEDCLS_VALS) ; \
	do \
	    dcl=dc$$n ;\
	    val=`echo 2 \^ $$n | bc` ;\
	    for f in $(MAKEDCLS:.f=) ;\
	    do \
		$(FTNCHEK) -makedcls=$$val $$f.f 1>/dev/null 2>/dev/null ; \
		if [ -f $$f.dcl ] ; \
		then \
		  if [ `wc -c $$f.dcl | awk '{printf("%s",$$1);}'` -eq 0 ] ; \
		  then \
		    $(CP) $$f.dcl $(VARY)/$$f.$$dcl ; \
		    echo ; echo "Empty declarations file" \
			 $(VARY)/$$f.$$dcl "should have been deleted" ; \
		  fi ; \
		else \
		   touch $$f.dcl ; \
		fi ; \
		$(MV) $$f.dcl $$f.$$dcl ; \
		$(COMPARE) $$f.$$dcl ; \
	    done ; \
	done
	@echo "done"


checkvcg:
	@-echo |awk '{printf("%s","checking -vcg setting:");}'
	@-for f in $(VCGLIST:.f=) ; \
	do \
	  $(FTNCHEK) -vcg $$f.f | fcl2vcg > $$f.vcg ; \
	  $(COMPARE) $$f.vcg ; \
	done
	@echo "done"

# CheckSetting is a "subroutine" with parameters SETTING=name of setting,
# RANGE=list of setting values, FLIST=list of files to check, and
# FLAGS=set of ftnchek flags to use for each case.  "Call" this routine
# by invoking make with appropriate macro definitions on command line.

CheckSetting:
	@for val in $(RANGE) ; \
	do \
	  for f in $(FLIST:.f=) ; \
	  do \
	    $(FTNCHEK) $(SETTING)=$$val $(FLAGS) $$f.f > $$f.fc$$val ; \
	    $(COMPARE) $$f.fc$$val ; \
	  done ; \
	done
